解密系列basic
解密系列[基础篇]
多字节存储顺序
两种编码区别:
**Big-Endian:**高位字节存入低地址,低位字节存入高地址,依次排列。
**Little-Endian :**低位字节存入低地址,高位字节存入高地址,反序排列 多字节数据存放顺序与CPU有关。
微处理器中存放顺序有正序( Big-Endian)和逆序(Little-Endian) (也称大端存储和小端存储)之分。
常见的Intel系列使用的编码方式属于Little-Endian类;某些RISC架构的CPU·OIBM6Power-PC等属于Big-Endian类。
补充:ASCII ( American Standard Code for InformationInterchange·美国信息互换标准代码) 0-256。
Unicode字符编码的编码范围是︰0-65535·它包含三套编码方式如 :UTF-8·UTF-16和UTF-32·它和ASCII的关系为ASCII字符编码是Unicode字符编码的一部分。
Win API简介:
Windows API就是windows应用程序接口,是针对microsoft windows操作系统家族的系统编程接口,这样的系统包括Windows 7 ·Windows Vista - WindowsXP -Windows Server 2003 ·Windows 2000-Windows95 ·Windows 98-Windows Me (Millennium Editon)和OWindows CE等几乎所有版本。它被设计为各种语言的程序调用,也是应用软件与Windows系统最直培的交互方式。
动态链接库︰动态链接就是把一些经常会共用的代码(静态链培的OBJ程序库)制作成DLL文件。当可执行文件调用到DLL文件内的函数时windows操作系统才会把DLL文件加载存储器内。
DLL文件本身的结构就是执i行文件(PE) ,当程序需求函数才进行链接,通过动态链接方式,存储器浪费的情形将大幅降低。 kernel32.dll:控制着系统的内存管理﹑数据的输入输出操作和中断处理。当Windows启动时,kernel32.dll就驻留在内存中特定的写保护区域,使别的程序无法占用这个内存区域。
user32.dll: Windows用户界面相关应用程序接口,用于包括Windows处理、基本用户界面等特性。如创建窗口和发送消息。
gdi32.dll:是Windows GDI图形用户界面相关程序,包含的函数用来绘制图像和显示文字。
句柄:是整个windows编程的基础。一个句柄是指使用的一个唯一的整数值,用于标志应用程序中的不同对象和同类对象中的不同的实例。
例:一个窗口,按钮,图标,滚动条,输出设备,控件或者文件等。应用程序能够通过句柄访问相应的对象的信息。
句柄是windows用来标志应用程序中建立的或是使用的唯一整数windows使用了大量的句柄来标志很多对象。
HWnd:带文本的窗口或控件的句柄。
IpString:指向接收文本的缓冲区的指针。
nMaxCount:指定要保存在缓冲区内的字符的最大个数,其中包含NULL字符
HWND GetDlgItem函数
1 | hwndScroll = GetDlgItem(hwnd, IDC_SCROLL); |
假设一个父窗口中有多个子窗口,那么本函数是返回一个子窗口句柄。第一个参数:父窗口句柄 第二个参数:子窗口 UINT
IDUINT GetDlgItemText函数
(检索与对话框中的控件关联的标题或文本)
1 | GetDlgItemText( |
GetwindowText函数
将指定窗口的标题条文本(如果存在)拷贝到一个缓存区内。 如果指定的窗口是一个控件,则拷贝控件的文本。 GetWindowText不能接收在其他应用程序中的控件的文本。
1 | int GetWindowText( |
UINT GetDlgItemInt函数
(将对话框中指定控件的文本转换为整数值)
1 | UINT GetDlgItemInt( |
MessageBox
(这个API方法用来创建、显示、操作一个消息框。它包含可设置的消息内容、标题,还可以添加预定义的图标、放置按钮)int
1 | int MessageBox( |
NT架构从内核到KERNEL32·USER32·GDI32都是纯32位实现。
NT架构标准字符集重头开发,统一使用Unicode字符集·兼容ASCII字符集。
区别:1.函数调用完后谁来清空栈2.入栈顺序(两者均自右向左)stdcall由子程序平衡栈 cdel(c语言标准)由调用值平衡栈回调函数。(callback)回调函数
Windows操作系统最大的特点就是其图形化的操作只面和多任务的管理。这些强大功能就是建立在其消息处理机制这个基础之上的。Windows系统与应用程序之间,应用程序与应用程序之间的通讯就是通过消息来触发,并靠对消息的响应和处理来完成。
Windows系统中有两种消息队列:一种是系统消息队列,另一种是应用程序消息队列。Windows本身是由消息驱动,当调试程序时跟踪一个消息会得到相当底层的答案。 Windows为当前执行的每个Windows程序维护一个消息队列。在发生某事件之后,系统将该事件转换为一个消息,并将消息投放入程序消息队列中。程序通过i行一块称之为消息循环的程序代码从消息队列中取出消息!其实∶消息不过是定义一个结构。定义一堆ID,在程序运行过程中调用switch case拦截去完成巳应的功能。
1 | while(GetMessage (&msg, NULL,0,0)) {TranslateMessage (&msg);//翻译消息 |
SendMessage函数 将指定的消息发送到一个或多个窗口。
1 | LRESULT [SendMessage](HWND hWnd,UINT Msg,WPARAM wParam,LPARAM IParam); |
WM_COMMAND
产生的条件:点击菜单, 点击加速键(键盘快捷键,是一个或几个按键的组合,它用于激活特定的命令,使用加速键不需要费力移动鼠标就能激活菜单项),点击窗口按钮,点击工具栏按钮。这些时候都有command消息产生。
wParam 高两个字节 通知码
wParam 低两字节 命令ID
lParam 发送命令消息的子窗体句柄。
WM_GETTEXT
WM_QUIT
WM_LBUTTONDOWN
WM_RBUTTONUP
WM_KEYUP
(可自行查询相应用法及作用 我也是大懒虫捏【😀】)
实模式
程序指令在执行过程中一般需要有各种数据,x86系列CS、DS、ES、FS、SS等用于指示不同用涂的数据段在内存中的位置。
x86系列使用中断机制来实现系统服务。
寄存器的扩展之路∶
8086以前( 8bit) ->8086( 16bit) ->80386(32bit)->现在的64bitCPU
寄存器(AL) ->(AX)->(EAX)->(RAX)
保护模式∶无论实模式还是保护模式根本的问题都为程序如何在其中运行。
和实模式下一样,保护模式下程序运行的实质仍是“CPU执行指令,操作相关数据”。主要改变的是寻址的方式,保护模式在寻址方式上“动了手脚””,为的是起到“保护作用”。
保护模式
一.不同任务之间的保护∶
通过把每个不同的任务放在不同的虚排地址空间中﹐来实现不同任务之间的隔离(即A程序不能访问和修改B程序的代码和数据)·以达到程序间的隔离;
二.同一任务的保护∶
在每一任务之内定义了4种保护级别·方别为0,1,2,3按环的方式表示.
其中,0级代表最高的权限级别,3级代表最低权限级别。按环的方式来表示。其中,环0、1、2为系统级,环3为用户级。
一般的系统只能使用环0和环3两个级别。 如上图所示,最外层的CodeAP1只能访问DataAP1。不能访问同级的另一应用程序的DataAP2;同样·CodeAP2只能访i6DataAP2 不能访DataAP1 。 要说明的是:如果应用程序拥有第0级的权限,那么它就可以执行所有的指令并访问所有的数据。
如果应用程序拥有的权限级别是第3级,它执行的指令是有限的,能访问的数据也是有限的(被保护) 。 操作系统的核心层是运行在Ring 0级。
WIN32子系统(KEDNET32.DLL 【内存的管理】USER32.DLL【操作用户的界面】 ,GDI32.DLL【操作图像的界面】等)是运行在Ring3级的,以提供与子程序的接口。
虚拟内存(确实存在于硬盘中)∶
虚拟内存并不是真正的内存·它是通过射( Map)的方法﹐使用的虚拟地址(VA)达到4GB(因为EIP32位索引的最大范围是4GB)。
这样规定︰每个应用程序可以被分配到2GB的虚拟地址·剩下的2GB留给操作系统自己用。( Windows NT中·应用程序甚至有3GB为虚拟地址 )
Windows是一个分时的多任务操作系统·CPU的时间被分割成一个个的时间片后行配给名个不同的应用程序·在一个时间片里,和这个应用程序护行无关的东西并不会又映射到线性地址中(这样EIP就索引不到)。
因比可以做到每个程序都拥有自己独立的4GB寻址空间·互不干扰。
要说明的是DLL与EXE不同【dll文件无自己的私有空间(动态链接文件)】
简单的虚拟内存的实现方法和过程∶
1.当一个应用程序被启动时,操作系统创建一个新的进程,并给这个进程行配2GB的虚拟地址(不是内存哦 是地址)。
2.虚拟内存管理器将应用程序的代码射到哪个程序的虚拟地址中的某个位置,并把当前所需要的代码读取到内存物理地址中。
3.如果用动态链接库DLL,DLL程序也会被映射到进程的虚拟地址空i间在需要的时候才被读入物理内存。
4.其他项目(像数据﹑堆栈等)的空间是首先从物理内存中行配,再反向映射到虚拟地址空间中的。
5.应用程序通过使用的他的虚拟地址空间中的地址开始执行·然后由虚拟内存管理器把每次的内存访问映射到物理位置去。
小结:
一.应用程序是不会直接访i问物理地址的。
二.虚拟内存管理器通过虚拟地址的访问请求,控制所有的物理地址访问;
三.每个程序都有独立的4G寻址空间·不同程虚拟地址空间是被互相隔离的; 四.DLL程序没有巨己的“私有”空间·它们称之为动态链接库文件·它们总是被射到其他应用程序的地址空间中的﹐作为其他应用程序的一部行运行。
最后,使用虚拟内存的好处是︰简化了内存的管理,并弥补物理内存的不足。另外以防止多任务环境下各个应用程序之间的冲突!
PE文件
PE的意思就是Portable Executable (可移植的挖行体)。它是Windows环境身所带的e行体文件格式。
它的一些特性继承由Unix Coff (commonobject file format)文件格式。
“portable executable”(己移植的执行体)意味着此文件格式是跨win32平台的:也就是说即使Windows 运行在非IntelCPU 上·任意win32平台的PE装载器都能识别和使用该文件格式。
基本上所有win32执行体(除了VxD和16位的DI)都用PE文件格式,包括NT的内核模式驱动程序( kernel mode drivers ) 。因而研究PE文件格式给了我们洞悉 Windows结构的良机。
PE文件用的是一个平面地址空间·所有代码和数据都合并在一起·组成一个很大结构文件的内容被行割为不同的区块(Section又称为区段·节等)·块中包含代码或数据。
每个区块都有巨己在内存中的属性:可读/写·只读等。
每个区块都有不同的名字,这用名字主要用来表示区块功能。
PE文件非常好的一个地方就是在磁盘上的数据结构与在内存中的结构是一致的。
当至统装载一个己i行文件到内存中·主要就是将一个PE文件的某一部方映射到地址空间中·这样﹐PE文件的数据结沟在磁盘和内存中就是一样的了。
(1)入口点(Entry Point)
PE文件巳行时的入口点(Entry Point) 。也就是说·程序在执行时的第一行代码地址应该就是这个值·有点像8086汇编语言中end start中start指向的入口地址。
(2)文件偏移地址(File Offset)
当PE文件储存在磁盘上的时候·各数据的地址称作文件的移地址·文件偏移地址人PE文件的第一个字节开始计数·起始值为0。
虚地地址(Virtual Address, VA)
由于Windows程序运行在保护模式下·所以应用程序访问存储器所使用的逻辑地址称为虚拟地址(因为他不是真正的物理地址·真正的物理地址被windows妈妈的保护机制保护起来)﹐又称为内存偏移地址(Memory Offset) 。实地址模式下的“段址也写地址∶偏移地址索引方式类似·虚樽地;成“段∶偏移量”的形式·但不同之处在于这里的段不再是段地切而是指段选择子。
例t :”0123:004010003’
0123∶表示段选择子。其数据存储在CS段选择器里。同一程序在不同系统环境下此值可能不同,因比我们不需要关心。
00401000∶此处表示内存中的虚拟地址。一般来说,同一个程序的向一条指令在不同系统环境下,此值相同(PE映射原理)。
基地址( ImageBase)
文件执行时将被映射到指定内存地址中·这个初始内存地址称为基地址。这个值是由PE文件本身设定的。
控照默认设置·用Visual C++建立的EXE文件基地址是00400000h。DLL支件基地址是10000000h。但这个值可自己在编译器设定的。